package cn.bone.mima.desaes;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class AesCBCDemo {
    public static void main(String[] args) throws Exception {


        // 原文
        String input = "武汉";
        // 定义key
        // 如果使用DES进行加密，秘钥必须是8个字节
        // 如果使用AES进行加密，秘钥必须是16个字节
        String key = "12345678abcdefgh";
        // 算法
        // 模式加密模式是EBC，默认填充模式的PKCS5Padding
        // 指定算法为 AES/CBC/PKCS5Padding
        String transformation = "AES/CBC/PKCS5Padding";
        // 加密类型
        String algorithm = "AES";
        // iv向量（这里可以使用key来生成iv向量，也可以指定其他的值作为iv向量）
        IvParameterSpec parameterSpec = new IvParameterSpec(key.getBytes());

        String encrypt = encrypt(input, key, transformation, algorithm, parameterSpec);
        String decrypt = decrypt(encrypt, key, transformation, algorithm, parameterSpec);
    }

    public static String encrypt(String input,
                                 String key,
                                 String transformation,
                                 String algorithm,
                                 IvParameterSpec parameterSpec) throws Exception{

        // 创建加密对象
        Cipher cipher = Cipher.getInstance(transformation);

        // 创建加密规则
        // 第一个参数表示key的字节
        // 第二个参数表示加密的类型（不是算法）
        SecretKey secretKey = new SecretKeySpec(key.getBytes("UTF-8"), algorithm);
        // 进行加密初始化
        // 第一个参数表示模式：加密模式，解密模式
        // 第二个参数表示加密规则
        // 第三个参数，IV向量
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
        // 调用加密方法
        // 参数表示原文的字节数组
        byte[] bytes = cipher.doFinal(input.getBytes("UTF-8"));

        // 使用base64编码
        byte[] encode = Base64.getEncoder().encode(bytes);
        // 9urMjL+nLEQxJQwjAkIu4g==
        String result = new String(encode, "UTF-8");
        System.out.println(result);
        return result;
    }

    public static String decrypt(String input,
                                 String key,
                                 String transformation,
                                 String algorithm,
                                 IvParameterSpec parameterSpec) throws Exception{

        // 创建加密对象
        Cipher cipher = Cipher.getInstance(transformation);
        // 创建加密规则
        // 第一个参数表示key的字节
        // 第二个参数表示加密的类型（不是算法）
        SecretKey secretKey = new SecretKeySpec(key.getBytes("UTF-8"), algorithm);
        // 进行加密初始化
        // 第一个参数表示模式：加密模式，解密模式
        // 第二个参数表示加密规则
        // 第三个参数，IV向量
        cipher.init(Cipher.DECRYPT_MODE, secretKey, parameterSpec);

        // 使用base64对密文解码
        byte[] decode = Base64.getDecoder().decode(input.getBytes("UTF-8"));
        // 调用解密方法
        // 参数表示密文的字节数组
        byte[] bytes = cipher.doFinal(decode);

        String result = new String(bytes,"UTF-8");
        // 武汉
        System.out.println(result);
        return result;
    }

}
